;^Z80^
TITLE FILE: TAPE_MANA:TOS HEWLETT-PACKARD: TAPE_MANAGER (c) Coleco 1983 Confidential
;NAME ^Rev 6 - DTT^
DESCR_ MACRO
.GOTO ENDESCR_1
Author: DTT
Project: ________, ___
Starting date:18feb83
Prom release Date:
Prom release Rev:
Header Rev: 3
********************************
* *
* TAPE_MANAGER DTT *
* *
********************************
Rev History (one line note indicating the change)
Rev. Date Name Change
6 11/16/83 DTT ADDED DEVICE ID TO SIMULATE DEVICE INDEPENDENCE
5 12spt83 DTT MODIFIED ERROR SYSTEM TO WRITE ERRORS TO CSA AREA
4 08aug83 DTT SIMULATES WRITES!
3 07jul83 DTT ADDED KILL_TAPE/CSA
2 30jun83 DTT STATE MACHINE FOR MULTI TASKING
1 05apr83 DTT BINK ON I/O ERROR, REMOVING TIMING STUFF, EI AND DI ADDED.
0 10feb83 DTT Initial Pseudo Code
NAME: TAPE_MANAGER (OVERLAY CONTROL)
FUNCTION: (LOAD OVERLAYS VIA SIMULATED I/O WITH THE HP64000)
INPUTS: (ACCUMULATOR = OVERLAY NUMBER)
OUTPUTS: (OVERLAY IS LOADED TO RAM ADDRESS)
PSEUDOCODE: (PASCAL type pseudocode of procedure.)
---------------- overlay request? Y ----------------
: :-----------------------> : :
:---->: IDLE : : RENAME :
: : : : :
: : :---------: : :
: ---------------- : ----------------
: /:\ overlay request? N :
: :______________: :
: :
: :
: :
: :
: :
: :
: \:/
: ---------------- ----------------
: : : : :
: : READ : <--------------------------: OPEN :
: : FIRST : : :
: : RECORD : : :
: ------:--------- ----------------
: :
: :
: \:/
: ---------------- ----------------
: : :------------------------> : :
: : READ : : MOVE DATA :
: : DATA : end of file? N : FROM BUFFER :
: : RECORD : <--------------------------: TO RAM :
: ---------------- --------:-------
: :
: end of file? Y
: \:/
: ---------------- ----------------
: : : : :
-----: PRE IDLE STATE :<---------------------------: CLOSE :
:(WAIT FOR CLOSE): : :
: : : :
---------------- ----------------
ENDESCR_1 MEND
DESC_a MACRO
.GOTO DESC_a
***********************************************************************************************
Each transition state looks like this:
from previous
=================:
state :
\:/
----------------: -----------------
: : I/O errors? Y : :
: TRANSITION :-------------------> : ERROR STATE :
:===>: : : (terminate) :----:
: : :=====: : : :
: ---------------- : ----------:------ :
: : : /:\ :
: : : : :
: sim i/o : \:/ :___________:
------------ ---------------- to state 6
function : :============>
complete? N : TEST FOR :
: ABORT :to state 7
: REQUEST :============>
----------------
no :
abort : to next
: state
\:/
DESC_a MEND
DESC_2 MACRO
.GOTO DESC_2
*
***************************************************************************************
*
COMMON ATTRIBUTE AREAS (COMMUNICATION BUFFER WITH HP)
ALL VALUES ARE HEXADECIMAL
1) ASSIGN FILENAME TO CA
CA CA+1 CA+2 CA+n
-------- -------- -------- -------- -------- -------- -------- --------
: 8A :LENGTH :FILENAME ------> : USER ID : NOT
: :BYTE :UP TO 9 BYTES : UP TO 5 BYTES : USED----->
-------- -------- -------- -------- -------- -------- -------- --------
LENGTH_BYTE := (((((LENGTH OF FILE NAME)+1)/2)-1)*32) + ((LENGTH OF USER ID)/2)*8)
FILENAME MUST BE ODD NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.
USER ID MUST BE EVEN NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.
2) OPEN
CA CA+1 CA+2
-------- -------- -------- -------- -------- -------- -------- --------
: 81 : 04 : 00 : NOT
: : : : USED------------------------------->
-------- -------- -------- -------- -------- -------- -------- --------
CA+1 MUST BE 04HEX DESIGNATES ABSOLUTE FILE WILL BE OPENED.
CA+2 MUST BE 00HEX DESIGNATES DISK NUMBER.
3) CLOSE
CA
-------- -------- -------- -------- -------- -------- -------- --------
: 82 : NOT
: : USED ----------------------------------------------->
-------- -------- -------- -------- -------- -------- -------- --------
4) READ
CA CA+1 CA+2 CA+4 CA+6
-------- -------- -------- -------- -------- -------- -------- --------
: 87 : 80 : #BYTES TO LOAD : N/A : N/A : LOAD ADDRESS
: : : MSB : LSB : : : MSB : LSB
-------- -------- -------- -------- -------- -------- -------- --------
CA+1 DEFINES THE BUFFER LENGTH IN WORDS - 1 MUST BE LOADED BEFORE CALLING SIM I/O
CA+2 DEFINES NUMBER OF BYTES TO MOVE TO RAM FROM THE SIM I/O BUFFER
CA+6 DEFINES THE RAM ADDRESS TO LOAD TO
CA+8 (NOT SHOWN) IS THE START OF THE SIM I/O BUFFER
NOTE: CA+2 AND CA+6 ARE ONE WORD LONG BUT NOT STORED AS Z80 WORDS.
THE Z80 EXPECTS WORD VALUES TO BE STORED LSB/MSB.
DESC_2
MEND
NEXT_STATE MACRO LP1
LD A,LP1 ;SOMETHING IN THE COMMAND BUFFER!
LD [TAPE_STATE],A
LD HL,[STATE_VECTORS+LP1+LP1]
LD [NEXT_STATE_ADDRESS],HL
JP END_OF_STATE_MACHINE
MEND
;SUBROUTINES CALLED:
; EXT
;OPERATING SYSTEM CALLS:
;EXTERNAL DATA AREAS USED:
EXT KILL_TAPE
EXT WRITE_TAPE
EXT CSA
EXT TAPE_STATE
EXT OVERLAY_NUMBER
;GLOBAL DATA AREAS DEFINED:
GLOBAL DEVICE_ID
;LOCAL EQUATES
CA EQU 07400H ;COMMON ATTRIBUTES AREA FOR SIM I/O
BUF_LEN EQU CA+1
FILETYPE EQU CA+1 ;FILETYPE ADDRESS IN C_A_
DISC_NUM EQU FILETYPE+1 ;DISK NUMBER ADDRESS IN C_A_
REC_LEN EQU CA+2 ;RECORD LENGTH ADDRESS IN C_A_
BUFFER EQU CA+8 ;I_O_BUFFER
RNAM_BUF EQU CA+1 ;RENAME BUFFER AREA
LOADADDR EQU CA+4 ;ADDRESS OF MEM ADDRESS OF OVERLAY
MAXBUFLN EQU 128 ;UP TO 128 WORDS MAY BE READ IN
ABSOLUTE EQU 004H ;FILE TYPE IS ABSOLUTE
OPEN EQU 081H
CLOSE EQU 082H
READ EQU 087H
WRITE EQU 089H
RENAME EQU 08AH
;GLOBAL EQUATES
; INCLUDE equate file name
PROG
GLOBAL TAPE_MANAGER
GLOBAL INITIALIZE_TAPE
INITIALIZE_TAPE:
GLOBAL INIT_TAPE
INIT_TAPE:
LD A,0 ;CLEAR THE HP64000 AREA
LD [CA],A
LD [CSA],A ;AND THE TAPE CONTROL STATUS AREA
DEC A
LD [OVERLAY_NUMBER],A ;MAKE THE OVERLAY NUMBER -1 (INVALID)
NEXT_STATE 0 ;SET THE IDLE STATE!
RET
TAPE_MANAGER:
;BEGIN (Ordinarily registers are restored; retain only the pushes and pops you need.)
LD A,[CA] ;TEST THE STATUS OF THE FILE
OR A
JP M,END_OF_STATE_MACHINE ;IF THERE IS A COMMAND IN THE BUFFER
JR Z,AB_REQ
CP 1 ;END OF FILE ON READ FROM HP64000
JP NZ,ERROR
;*
;* AT THIS POINT ANY SIM I/O FUNCTIONS ARE COMPLETE; TEST FOR ABORTS (KILLS)
;*
GLOBAL AB_REQ
AB_REQ: LD A,[CSA] ;IF COMMAND IS TO KILL TAPE COMMAND
CP KILL_TAPE
JR NZ,CASE_STATE
LD A,[TAPE_STATE] ;CHECK THE STATE OF THE TAPE
;*
CP 3 ;CHECK STATE 0,1,2
JP C,STATE_PRE_IDLE ;FILE NOT OPENED
;*
CP 6 ;STATE 3,4,5
JP C,STATE_CLOSE ;FILE OPENED TRY TO CLOSE IT
;*
;* FALL THRU TO CASE STATEMENT ;IF STATE = 6,7
;* ;FILE IS TRYING TO CLOSE
;*
;*
;* CASE TAPE_STATE,(IDLE,RENAME,OPEN,READ1,READ2,MOVE2VRAM,CLOSE,PRE_IDLE)
;*
CASE_STATE:
;*
;*
LD HL,[NEXT_STATE_ADDRESS]
JP [HL]
STATE_VECTORS:
DEFW STATE_IDLE ;STATE 0
DEFW STATE_RENAME ; 1
DEFW STATE_OPEN ; 2
DEFW STATE_READ_1 ; 3
DEFW STATE_READ_2 ; 4
DEFW STATE_MOVE2RAM ; 5
DEFW STATE_CLOSE ; 6
DEFW STATE_PRE_IDLE ; 7
DEFW WRITE_1
;*
;* IF THE MACHINE IS IDLE IT'S OK TO TEST FOR ANOTHER READ REQUEST
;*
STATE_IDLE: ;STATE 0
LD A,[CSA] ;TEST THE COMMAND STATUS AREA
OR A
JP Z,END_OF_STATE_MACHINE
;*
NEXT_STATE 1
;*
;* ASSIGN THE SIM I/O FILE TO THE CURRENT OVERLAY NAME
;*
STATE_RENAME: ;STATE 1
LD A,[OVERLAY_NUMBER]
LD HL,SAMPLE_NAME
LD DE,RNAM_BUF ;POINT TO THE RENAME BUFFER IN THE COMMON ATTRIBUTES AREA
LD BC,SAMPLE_NAME_LEN ;NO NAME COULD BE MORE THAN TEN BYTES LONG COULD IT?
LDIR ;MOVE THE OVERLAY DATA TO THE RENAME BUFFER
;*
;*
;*
LD BC,10*256+"0" ;GET THE OVERLAY NUMBER INTO ASCII
OV_2_ASCII_1:
OR A
SBC A,B ;DIVIDE OVERLAY NUMBER BY 10
INC C ;SET THE NUMBER OF TENS IN C (DOESN'T RESET CARRY)
JR NC,OV_2_ASCII_1 ;CARRY WAS SET BY SUBTRACT IF B>A
DEC C ;SAVE THE TENS BYTE
ADD A,B ;ADD TENS TO GET THE REMAINDER
LD B,"0" ;SAVE THE ONES BYTE
ADD A,B
LD B,A
LD A,C
CP "0" ;CONVERT TO ASCII
JR NZ,OV_2_ASCII_2
LD A,"_" ;SPECIAL CASE
OV_2_ASCII_2:
LD [DE],A ;DE IS POINTING TO THE FILENAME FROM THE LDIR ABOVE
INC DE
LD A,B
LD [DE],A
;*
;* ASSIGN THE FILE
;*
LD A,RENAME
LD [CA],A
;*
NEXT_STATE 2 ;NEXT OPEN
;*
;*
STATE_OPEN: ;STATE 2
;*
;* OPEN THE FILE
;*
LD A,ABSOLUTE ;LOAD THE FILE TYPE
LD [FILETYPE],A
LD A,0 ;DISK NUMBER
LD [DISC_NUM],A
LD A,OPEN ;OPEN THE CURRENT FILE
LD [CA],A
LD A,[CSA] ;NEXT STATE READ OR WRITE?
NEXT_STATE 3 ;NEXT STATE = READ_1
STATE_READ_1: ;STATE 3
;*
;* READ THE FIRST RECORD TO SKIP OVER IT
;*
LD A,MAXBUFLN ;SET THE INPUT BUFFER LENGTH
LD [BUF_LEN],A ;
LD A,READ
LD [CA],A ;READ THE FIRST RECORD
NEXT_STATE 4
;*
;* READ REMAINING RECORDS AND MOVE TO RAM
;*
STATE_READ_2: ;STATE 4
LD A,MAXBUFLN ;SET THE INPUT BUFFER LENGTH
LD [BUF_LEN],A ;
LD A,READ ;
LD [CA],A
NEXT_STATE 5 ;NEXT STATE = READ A DATA RECORD
;*
;* MOVE THE LAST BUFFER TO RAM
;*
STATE_MOVE2RAM: ;STATE 5
LD A,[CA] ;CHECK THE RETURN STATUS
OR A
JR Z,NO_EOF ;END OF FILE?
;*
;*
NEXT_STATE 6 ;NEXT STATE = CLOSE FILE
NO_EOF: ;MOVE THE CURRENT OVERLAY TO MEMORY
LD HL,[REC_LEN] ;GET THE NUMBER OF BYTES TO MOVE TO RAM
LD C,H
LD B,L
;*
LD HL,[LOADADDR] ;GET THE LOAD ADDRESS AND CHECK TO SEE IF IT IS IN VRAM
LD D,L
LD E,H
LD HL,BUFFER ;FROM ADDRESS
LD A,[CSA]
CP WRITE_TAPE
JR Z,WRITE_1
LDIR
;*
NEXT_STATE 4 ;NEXT STATE = READ A DATA RECORD
;*
;* CLOSE OVERLAY FILE
;*
STATE_CLOSE: ;STATE 6
LD A,CLOSE ;CLOSE THE FILES
LD [CA],A
NEXT_STATE 7 ;NEXT STATE = PRE-IDLE
;*
;*
;* NEXT STATE IS IDLE
;*
STATE_PRE_IDLE: ;STATE 7
LD A,0 ;NEXT STATE = PRE-IDLE
LD [CSA],A ;CLEAR THE COMMAND STATUS BUFFER
DEC A
LD [OVERLAY_NUMBER],A ;SET THE OVERLAY NUMBER TO OUT OF RANGE
NEXT_STATE 0
;*
;* WRITE OUT 256 DATA BYTES TO AN OVERLAY! OH BOY!
;*
WRITE_1: ;GET HERE FROM MOVE2RAM1
EX DE,HL
LDIR
LD A,WRITE
LD [CA],A
NEXT_STATE 6
;*
;*
;*
; END (TAPE_MANAGER)
END_OF_STATE_MACHINE:
XOR A
RET
;***************************************************************************
;***************************************************************************
ERROR:
; BEGIN (Ordinarily registers are restored; retain only the pushes and pops you need.)
LD C,A
LD A,[OVERLAY_NUMBER] ;SAVE THE OVERLAY NUMBER IN A
LD B,A
LD A,[TAPE_STATE]
LD HL,0 ;B HAS THE FUNCTION CODE
LD [HL],A ;C HAS THE ERROR CODE
;
; LD [HL] HAS JUST CAUSED A BINK TO OCCUR ON THE HP64000
; THIS IS TO LET THE USER KNOW THERE HAS BEEN AN ERROR
;
XOR A
LD [CA],A ;CLEAR THE ERROR FROM THE HP64000
INC A ;PRETEND THE ERROR WAS A CRC CHECK FROM ADAM'S TAPE
LD [CSA],A
LD HL,[STATE_VECTORS+0000]
LD [NEXT_STATE_ADDRESS],HL
RET
; END (TAPE_ERR)
;***************************************************************************
;***************************************************************************
;
; OVERLAY NAMES
;
; -------- -------- -------- -------- --------
; :LENGTH :FILENAME ------> : USER ID :
; :BYTE :UP TO 9 BYTES : UP TO 5 BYTES :
; -------- -------- -------- -------- --------
; LENGTH_BYTE := (((((LENGTH OF FILE NAME)+1)/2)-1)*32) + ((LENGTH OF USER ID)/2)*8)
; FILENAME MUST BE ODD NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.
; USER ID MUST BE EVEN NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.
;
;*****************************************************************************************
;*****************************************************************************************
;*
;* OVERLAY NAME 0
;*
SAMPLE_NAME
OVLAY0 DEFB FL_NM_LN0*32+US_ID_LN0*8 ;LENGTH DESCRIPTION BYTE
NAM_0 DEFB "OVL_1" ;MUST BE ODD NUMBER OF LETTERS
USID0 DEFB "" ;MUST BE EVEN NUMBER OF LETTERS
FL_NM_LN0 EQU ((USID0-NAM_0+1)/2)-1 ;LENGTH OF FILENAME IN WORDS
US_ID_LN0 EQU ($-USID0)/2 ;LENGTH OF USERID IN WORDS
SAMPLE_NAME_LEN EQU $-SAMPLE_NAME-2 ;NUMBER OF BYTES TO MOVE = 4
;***********************************************************************
DATA
GLOBAL NEXT_STATE_ADDRESS
NEXT_STATE_ADDRESS DEFS 2 ;POINTER TO NEXT ENTRY STATE
DEVICE_ID DEFS 1 ;DEVICE INDEPENDENCE SIMULATED